package com.examsys.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.examsys.po.Admin;
import com.examsys.po.AdminRolesSettings;
import com.examsys.service.AdminRolesSettingsService;
import com.examsys.service.AdminService;
import com.examsys.util.JsonUtils;
import com.examsys.util.TreeNode;

/**
 * 登录控制层
 *
 */
@WebServlet("/login")
public class LoginController extends BaseController{
	//log4j日志对象
	private Logger log = Logger.getLogger(this.getClass());
	
	private AdminService adminService;//业务逻辑层对象
	
	private AdminRolesSettingsService adminRolesSettingsService;//业务逻辑层对象
	
	/**
	 * 初始化工作，这里主要是给业务逻辑层属性做初始化
	 */
	@Override
	public void init() throws ServletException {
		super.init();
		adminService=lookUp("adminService");
		adminRolesSettingsService=lookUp("adminRolesSettingsService");
	}
	/**
	 * 
	 * @param req
	 * @param admin 接收登录表单提交过来的数据
	 * @param code  接收验证码
	 * @return
	 */
	public void login(HttpServletRequest request, HttpServletResponse response){
		String code = request.getParameter("code");
		String user_name = request.getParameter("user_name");
		String user_pass = request.getParameter("user_pass");
		
		log.info("接收到登录信息:"+user_name+","+user_pass+",验证码:"+code);//把admin放到日志
		
		try {
			//从服务器缓存中拿出先前放置的验证码
			String sessionCode=(String)request.getSession().getAttribute("code");
			if(!sessionCode.equals(code)){//与页面传过来的验证码对比
				request.setAttribute("msg", "验证码不正确");
				request.getRequestDispatcher("index.jsp").forward(request, response);//如果不匹配则返回登录页
			}
			
			//通过用户名去获取管理员
			Admin dbAdmin = adminService.getAdminByUserName(user_name);
			
			if(dbAdmin==null){//如果拿不到管理员
				request.setAttribute("msg", "账号不存在");
				request.getRequestDispatcher("index.jsp").forward(request, response);//如果不匹配则返回登录页
			}
			
			if(!user_pass.equals(dbAdmin.getUser_pass())){//验证当前录入的密码与数据库返回来的密码是否相等
				request.setAttribute("msg", "密码不正确");
				request.getRequestDispatcher("index.jsp").forward(request, response);//如果不匹配则返回登录页
			}
			
			request.getSession().setAttribute("ADMIN", dbAdmin);//将管理员对象放入session缓存中，方便其他模块使用
			response.sendRedirect("main.jsp");//重定向到主界面页
		
		} catch (Exception e) {
			log.error("登录失败", e);
		}
		
	}
	
	/**
	 * 登录成功后，进入主界面时，左边的树导航栏需要的数据
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	public void ajaxTree(HttpServletRequest request, HttpServletResponse response) throws IOException{
		
		//从session缓存中拿出登录的管理员对象
		Admin admin = (Admin)request.getSession().getAttribute("ADMIN");
		String role_privelege = admin.getAdminRoles().getRole_privelege();
		//因为之前存在数据中是一串用逗号隔开的功能编号
		String[] priveleges = role_privelege.split(",");
		List<TreeNode> list=new ArrayList<TreeNode>();
		try {
			
			for(String id:priveleges){//遍历权限所拥有的功能项
				AdminRolesSettings adminRolesSettings = adminRolesSettingsService.get(Integer.valueOf(id));
				
				if(adminRolesSettings!=null&&adminRolesSettings.getAdminRolesSettings()==null){
					
					TreeNode treeNode=new TreeNode();//创建树节点对象
					treeNode.setId(adminRolesSettings.getId());//节点编号
					treeNode.setText(adminRolesSettings.getName());
					treeNode.getAttributes().put("url", adminRolesSettings.getUrl());//节点超链接
					list.add(treeNode);//将树节点放入集合中
				}
			}
		} catch (Exception e) {
			log.error("初始化主界面树数据失败", e);
		}
		//最终给JsonUtils转换为json数据输出给浏览器
		response.getWriter().write(JsonUtils.objectToJson(list));
	}
	
	/**
	 * 生成验证码
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	public void code(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//在内存中创建图像
		int width=60,height=20;
		BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//获取图形上下文
		Graphics g=image.getGraphics();
		//创建随机数对象
		Random random=new Random();
		//设定背景色
		g.setColor(getRandColor(200,250));
		g.fillRect(0, 0, width, height);
		
		//设置字体
		g.setFont(new Font("Times New Roman",Font.PLAIN,18));
		
		//随机产生155条干扰线，使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(60,200));
		for(int i=0;i<155;i++){
			int x=random.nextInt(width);
			int y=random.nextInt(height);
			int xl=random.nextInt(12);
			int yl=random.nextInt(12);
			g.drawLine(x, y, x+xl, y+yl);
		}
		
		//随机产生认证码(4位数字)
		String sRand="";
		for(int i=0;i<4;i++){
			String rand=String.valueOf(random.nextInt(10));
			sRand+=rand;
			//将认证码显示到图象中
			g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
			g.drawString(rand, 13*i+6, 16);
		}
		
		//将认证码存入SESSION
		request.getSession().setAttribute("code", sRand);
		//图象生效
		g.dispose();
		
		ByteArrayOutputStream output=new ByteArrayOutputStream();
		ImageOutputStream imageOut=ImageIO.createImageOutputStream(output);
		ImageIO.write(image, "JPEG", imageOut);
		imageOut.close();
		response.getOutputStream().write(output.toByteArray());
	}
	
	private Color getRandColor(int fc,int bc){
		//创建随机数对象
		Random random=new Random();
		if(fc>255){
			fc=255;
		}
		
		if(bc>255){
			bc=255;
		}
		
		int r=fc+random.nextInt(bc-fc);
		int g=fc+random.nextInt(bc-fc);
		int b=fc+random.nextInt(bc-fc);
		return new Color(r,g,b);
	}
}
